/**
 * 定义向量类,包含向量的各类计算方法
 * @param x
 * @param y
 * @constructor
 */
function Vector(x, y) {
    this.x = x;
    this.y = y
}
// 将速度对象的运算符重载
Vector.prototype = {
    // 向量除实数
    div: function (num) {
        return new Vector(this.x / num, this.y / num)
    },
    // 向量自除实数
    idiv: function (num) {
        this.x /= num;
        this.y /= num
    },
    // 向量乘实数
    mul: function (num) {
        return new Vector(this.x * num, this.y * num)
    },
    // 向量自乘实数
    imul: function (num) {
        this.x *= num;
        this.y *= num
    },
    // 限制到最大值和最小值范围内,并返回新的向量
    limit: function (max, min) {
        if (this.mag() > max) {
            var unit = this.unit();
            return new Vector(unit.x * max, unit.y * max)
        }else if (this.mag() < min) {
            var unit = this.unit();
            return new Vector(unit.x * min, unit.y * min)
        }
        return this
    },

    // 将自身限制到最大值和最小值之内
    ilimit: function (max, min) {
        let unit = this.unit();
        if (this.mag() > max) {
            this.x = unit.x * max;
            this.y = unit.y * max
        }else if (this.mag() < min) {
            this.x = unit.x * min;
            this.y = unit.y * min
        }
    },

    // 向量求模长
    mag: function () {
        return Math.sqrt(this.x * this.x + this.y * this.y)
    },

    // 返回单位化后的新向量
    unit: function () {
        let mag = this.mag();
        return new Vector(this.x / mag, this.y / mag)
    },

    // 向量自身单位化
    iunit: function () {
        let mag = this.mag();
        this.x = this.x / mag;
        this.y = this.y / mag;
    },

    // 加上一个矢量,并返回一个新的向量
    add: function (v2) {
        return new Vector(this.x + v2.x, this.y + v2.y)
    },

    // 向量自加
    iadd: function (v2) {
        this.x += v2.x;
        this.y += v2.y
    },
    // 减去或者给自身减一个矢量
    sub: function (v2) {
        return new Vector(this.x - v2.x, this.y - v2.y)
    },
    isub: function (v2) {
        this.y -= v2.x;
        this.y -= v2.y
    },

    /* 向量与第二个向量v2的点乘 */
    dot: function (v2) {
        return (this.x * v2.x + this.y * v2.y)
    },

    /* 向量与第二个向量v2的叉乘 */
    cross: function (v2) {
        return (this.x * v2.y) - (this.y * v2.x)
    },

    // 到dest点的距离
    euc2d: function (dest) {
        return Math.sqrt((this.x - dest.x) * (this.x - dest.x) +
            (this.y - dest.y) * (this.y - dest.y))
    },

    // 目标向量dest在本向量方向上的投影的矢量(前进方向)
    forward: function (dest) {
        var vx = this.x * ((this.x * dest.x) + (this.y * dest.y)) / ((this.x * this.x) + (this.y * this.y));
        var vy = this.y * ((this.x * dest.x) + (this.y * dest.y)) / ((this.x * this.x) + (this.y * this.y));
        return new Vector(vx, vy)
    },

    // 目标向量dest在本向量垂直方向上的投影的矢量(侧面方向)
    steer: function (dest) {
        let vx = this.y * ((this.y * dest.x) - (this.x * dest.y)) / ((this.x * this.x) + (this.y * this.y));
        let vy = -1 * this.x * ((this.y * dest.x) - (this.x * dest.y)) / ((this.x * this.x) + (this.y * this.y));
        return new Vector(vx, vy)
    },

    // 对象的拷贝
    copy: function () {
        return new Vector(this.x, this.y);
    },

    // 目标dest在本向量的夹角的cos值
    cosAngle: function (dest) {
        let this_mag = this.mag();
        let dest_mag = dest.mag();
        if (this_mag > 0 && dest_mag > 0) {
            let dot_product = dest.x * this.x + dest.y * this.y;
            return dot_product / (dest_mag * this_mag);
        }
    },

    // 目标dest顺时针到当前向量夹角的sin值
    sinAngle: function (dest) {
        let this_mag = this.mag();
        let dest_mag = dest.mag();
        if (this_mag > 0 && dest_mag > 0) {
            let cross_product = this.cross(dest);
            return cross_product / (dest_mag * this_mag);
        }
    },

    // 向量转变成字符串, fixNum为小数点后保留几位
    toString: function ( height, fixNum) {
        height = height || this.y * 2;  // 默认为2倍的y值
        fixNum = fixNum || 2;
        var info = "(";
        info += this.x.toFixed(fixNum) + "," + (height - this.y).toFixed(fixNum);
        info += ")";
        return info

    },

    // 求得垂直向量
    //vertical: function(){
    //    var x1 = -1 * this.y / (this.x * this.x + this.y);
    //    var y1 = this.x / (this.x * this.x + this.y);
    //    return new Vector(x1,y1)
    //}

    vertical: function(){
        var x1 = this.mag() * this.y / (this.x * this.x + this.y * this.y);
        var y1 = -1 * this.mag() * this.x / (this.x * this.x + this.y * this.y);
        return new Vector(x1,y1)
    }
};

export default Vector;